home *** CD-ROM | disk | FTP | other *** search
/ Power Programmierung / Power-Programmierung (Tewi)(1994).iso / magazine / pctchnqs / 1991 / number6 / l3.asm < prev    next >
Assembly Source File  |  1991-11-11  |  7KB  |  193 lines

  1. ;  QSCAN3.ASM
  2. ;  David Stafford
  3. ;  8/23/91
  4.  
  5.         COMMENT $
  6.  
  7. How it works
  8. ------------
  9. The idea is to go through the buffer fetching each letter-pair (words
  10. rather than bytes).  The carry flag indicates whether we are
  11. currently in a (text)word or not.  The letter-pair fetched from the
  12. buffer is converted to a 16-bit address by shifting it left one bit
  13. (losing the high bit of the second character) and putting the carry
  14. flag in the low bit.  The high bit of the count register is set to
  15. 1.  Then the count register is added to the byte found at the given
  16. address in a large (64k, naturally) table.  The byte at the given
  17. address will contain a 1 in the high bit if the last character of the
  18. letter-pair is a word-letter (alphanumeric or apostrophe).  This will
  19. set the carry flag since the high bit of the count register is also a
  20. 1. The low bit of the byte found at the given address will be one if
  21. the second character of the previous letter-pair was a word-letter
  22. and the first character of this letter-pair is not a word-letter. It
  23. will also be 1 if the first character of this letter-pair is a
  24. word-letter but the second character is not.  This process is
  25. repeated.  Finally, the carry flag is saved to indicate the final
  26. in-a-word/not-in-a-word status.  The count register is masked to
  27. remove the high bit and the count of words remains in the count
  28. register.
  29.  
  30. Sound complicated?  You're right!  But it's fast!
  31.  
  32. The beauty of this method is that no jumps are required, the
  33. operations are fast, it requires only one table and the process can
  34. be repeated (unrolled) many times.  QSCAN3 can read 256 bytes without
  35. jumping.
  36.  
  37.         COMMEND $
  38.  
  39.                 .model small
  40.                 .code
  41.  
  42. Test1           macro   x,y                     ;9 or 10 bytes
  43. Addr&x:         mov     di,[bp+y]               ;3 or 4 bytes
  44.                 adc     di,di
  45.                 or      ax,si
  46.                 add     al,[di]
  47.                 endm
  48.  
  49. Test2           macro   x,y                     ;7 or 8 bytes
  50. Addr&x:         mov     di,[bp+y]               ;3 or 4 bytes
  51.                 adc     di,di
  52.                 add     ah,[di]
  53.                 endm
  54.  
  55. Scan            =       128                     ;scan 256 bytes at a time
  56.  
  57. Buffer          =       4                       ;parms
  58. BufferLength    =       6
  59. CharFlag        =       8
  60. WordCount       =       10
  61.  
  62.                 public _ScanBuffer
  63. _ScanBuffer     proc near
  64.                 push    bp
  65.                 mov     bp,sp
  66.                 push    si
  67.                 push    di
  68.  
  69.                 xor     cx,cx
  70.                 mov     si,[bp+Buffer]          ;si = text buffer
  71.                 mov     ax,[bp+BufferLength]    ;dx = length in bytes
  72.                 shr     ax,1                    ;dx = length in words
  73.                 jnz     NormalBuf
  74. OneByteBuf:
  75.                 mov     ax,seg WordTable
  76.                 mov     es,ax
  77.  
  78.                 mov     di,[bp+CharFlag]
  79.                 mov     bh,[di]                 ;bh = old CharFlag
  80.                 mov     bl,[si]                 ;bl = character
  81.                 add     bh,'A'-1                ;make bh into character
  82.                 add     bx,bx                   ;prepare to index
  83.                 mov     al,es:[bx]
  84.                 cbw                             ;get hi bit in ah (then bh)
  85.                 shr     al,1                    ;get low bit
  86.                 adc     cx,cx                   ;cx = 0 or 1
  87.                 xchg    ax,bx
  88.                 jmp     CleanUp
  89. NormalBuf:
  90.                 push    bp                      ;(1)
  91.                 pushf                           ;(2)
  92.  
  93.                 cwd                             ;dx = 0
  94.                 mov     cl,Scan
  95.                 div     cx
  96.                 or      dx,dx                   ;remainder?
  97.                 jz      StartAtTheTop           ;nope, do the whole banana
  98.  
  99.                 sub     cx,dx
  100.                 sub     si,cx                   ;adjust buf pointer
  101.                 sub     si,cx
  102.                 inc     ax                      ;adjust for partial read
  103.  
  104. StartAtTheTop:  mov     bx,dx                   ;get index for start...
  105.                 shl     bx,1
  106.                 mov     di,LoopEntry[bx]        ;...address in di
  107.  
  108.                 xchg    dx,ax                   ;dx is the loop counter
  109.                 xor     cx,cx                   ;total word count
  110.  
  111.                 mov     bx,[bp+CharFlag]
  112.                 mov     bl,[bx]                 ;bl = old CharFlag
  113.  
  114.                 mov     bp,seg WordTable
  115.                 mov     ds,bp
  116.  
  117.                 mov     bp,si                   ;scan buffer with bp
  118.                 mov     si,8080h                ;hi bits
  119.                 mov     ax,si                   ;init local word counter
  120.  
  121.                 shr     bl,1                    ;carry = old CharFlag
  122.                 jmp     di
  123.  
  124.                 align   2
  125. Top:            add     bx,bx                   ;restore carry
  126. n               =       0
  127.                 rept    Scan/2
  128.                 Test1   %n,%n*2
  129.                 Test2   %n+1,%n*2+2
  130. n               =       n+2
  131.                 endm
  132. EndCount:
  133.                 sbb     bx,bx                   ;save carry
  134.  
  135. if              Scan ge 128                     ;because al+ah may equal 128!
  136.                 or      ax,si
  137.                 add     al,ah
  138.                 mov     ah,0
  139. else
  140.                 add     al,ah
  141.                 and     ax,7fh                  ;mask
  142. endif
  143.                 add     cx,ax                   ;update word count
  144.                 mov     ax,si
  145.                 add     bp,Scan*2
  146.  
  147.                 dec     dx                      ;any left?
  148.                 jng     Quit
  149.                 jmp     Top
  150.  
  151. Quit:           popf                            ;(2) even or odd buffer?
  152.                 jnc     ItsEven
  153.  
  154.                 clc
  155.                 Test1   Odd,-1
  156.                 sbb     bx,bx                   ;save carry
  157.                 shr     ax,1
  158.                 adc     cx,0
  159. ItsEven:
  160.                 push    ss                      ;restore ds
  161.                 pop     ds
  162.                 pop     bp                      ;(1)
  163. CleanUp:
  164.                 mov     si,[bp+WordCount]
  165.                 add     [si],cx
  166.                 adc     word ptr [si+2],0
  167.  
  168.                 and     bh,1                    ;save only the carry flag
  169.                 mov     si,[bp+CharFlag]
  170.                 mov     [si],bh
  171.  
  172.                 pop     di
  173.                 pop     si
  174.                 pop     bp
  175.                 ret
  176. _ScanBuffer     endp
  177.  
  178.                 .data
  179. Address         macro   X
  180.                 dw      Addr&X
  181.                 endm
  182.  
  183. LoopEntry       label word
  184. n               =       Scan
  185.                 REPT Scan
  186.                 Address %n MOD Scan
  187. n               =       n - 1
  188.                 ENDM
  189.  
  190.                 .fardata WordTable
  191. include         qscan3.inc                      ;built by MAKETAB
  192.                 end
  193.